#include "PM25Sensor.h"


#include <iostream>
#include <sqlite3.h>
#include <cjson/cJSON.h>
#include <wiringPi.h>
#include "Buffer.h"

int PM25Sensor::Filter(int m)
{
    static int flag_first = 0, _buff[10], sum;
    const int _buff_max = 10;
    int i;

    if (flag_first == 0)
    {
        flag_first = 1;

        for (i = 0, sum = 0; i < _buff_max; i++)
        {
            _buff[i] = m;
            sum += _buff[i];
        }
        return m;
    }
    else
    {
        sum -= _buff[0];
        for (i = 0; i < (_buff_max - 1); i++)
        {
            _buff[i] = _buff[i + 1];
        }
        _buff[9] = m;
        sum += _buff[9];

        i = sum / 10.0;
        return i;
    }
}

PM25Sensor::PM25Sensor(int deviceId, int iledPin, int channel, string dbName, string dataTbaleName, string configTableName)
    :Sensor(deviceId, dbName, dataTbaleName, configTableName), iledPin(iledPin), channel(channel)
{

}

SensorConfig PM25Sensor::readConfigFromBuffer()
{
    string configJson;
    SensorConfig config;
    if (buffer.readConfigJsonFromBuffer(configJson))
    {
        cout << "读取pm2.5配置失败使用默认配置: sample = 1 \n";
        config.setSample(1);
        writeConfigToBuffer(config);
    }
    cJSON* configJsonObj = cJSON_Parse(configJson.c_str());
    cJSON* sample = cJSON_GetObjectItemCaseSensitive(configJsonObj, "sample");
    if (configJsonObj && sample)
    {
        config.setSample(sample->valueint);
        cJSON_free(configJsonObj);
        cJSON_free(sample);
    }
        
    return config;
}

void PM25Sensor::writeConfigToBuffer(SensorConfig config)
{
    cJSON* configObj = cJSON_CreateObject();
    cJSON* sample = cJSON_CreateNumber(config.getSample());
    cJSON_AddItemToObject(configObj, "sample", sample);

    this->buffer.writeConfigJsonToBuffer(cJSON_Print(configObj));
    cJSON_free(configObj);
    cJSON_free(sample);
}

void PM25Sensor::recordSensorData()
{
    if (m_density > 0)
    {
        cJSON* pm25Obj = cJSON_CreateObject();
        cJSON* density = cJSON_CreateNumber(this->m_density);
        cJSON* date = cJSON_CreateString(this->buffer.getCurrentTime().c_str());
        cJSON_AddItemToObject(pm25Obj, "density", density);
        cJSON_AddItemToObject(pm25Obj, "date", date);
        buffer.writeDataJsonToBuffer(cJSON_Print(pm25Obj));
        cJSON_free(pm25Obj);
        cJSON_free(density);
        cJSON_free(date);
    }
   
}

void PM25Sensor::readSensorData()
{
    float voltage;
    int adcValue;
    float density;

    pinMode(DataOut, INPUT);
    pullUpDnControl(DataOut, PUD_UP);

    pinMode(Clock, OUTPUT);
    pinMode(Address, OUTPUT);

    pinMode(iledPin, OUTPUT);
    digitalWrite(iledPin, LOW);

    digitalWrite(iledPin, HIGH);
    delayMicroseconds(280);
    adcValue = ADC_Read(channel);
    // printf("%d\n", adcValue);
    digitalWrite(iledPin, LOW);

    adcValue = Filter(adcValue);
    voltage = (5 / 1024.0) * adcValue;
   
    if (voltage >= NO_DUST_VOLTAGE)
    {
        //voltage -= NO_DUST_VOLTAGE;

        density = COV_RATIO * voltage - 0.0999;
    }
    else
        density = 0;


    delay(1000);

    m_density = density > 0 ? density * 1000: 0;
    
}
